package com.material.supplier.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.material.common.exception.ServiceException;
import com.material.common.utils.Arith;
import com.material.common.utils.DateUtils;
import com.material.common.utils.JsonUtils;
import com.material.common.utils.bean.BeanUtil;
import com.material.factory.domain.FactoryFuel;
import com.material.factory.domain.FactoryFuelRule;
import com.material.factory.domain.FactoryInfo;
import com.material.factory.domain.FactoryReceivingPlan;
import com.material.factory.mapper.FactoryFuelMapper;
import com.material.factory.mapper.FactoryFuelRuleMapper;
import com.material.factory.mapper.FactoryInfoMapper;
import com.material.factory.mapper.FactoryReceivingPlanMapper;
import com.material.factory.vo.FactoryFuelRuleSaveVo;
import com.material.pound.domain.FuelPound;
import com.material.pound.mapper.FuelPoundMapper;
import com.material.supplier.domain.SupplierCar;
import com.material.supplier.domain.SupplierInfo;
import com.material.supplier.mapper.SupplierCarMapper;
import com.material.supplier.mapper.SupplierInfoMapper;
import com.material.supplier.params.SupplierReservationQuery;
import com.material.supplier.vo.SupplierReservationDataVo;
import com.material.supplier.vo.SupplierReservationVo;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.material.supplier.mapper.SupplierReservationMapper;
import com.material.supplier.domain.SupplierReservation;
import com.material.supplier.service.ISupplierReservationService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 供应商预约送料Service业务层处理
 *
 * @author ruoyi
 * @date 2025-05-07
 */
@Service
public class SupplierReservationServiceImpl implements ISupplierReservationService
{
    @Autowired
    private SupplierReservationMapper supplierReservationMapper;
    @Autowired
    private SupplierCarMapper supplierCarMapper;
    @Autowired
    private FactoryFuelMapper factoryFuelMapper;
    @Autowired
    private FactoryInfoMapper factoryInfoMapper;
    @Autowired
    private FactoryFuelRuleMapper factoryFuelRuleMapper;
    @Autowired
    private SupplierInfoMapper supplierInfoMapper;
    @Autowired
    private FuelPoundMapper fuelPoundMapper;
    @Autowired
    private FactoryReceivingPlanMapper factoryReceivingPlanMapper;

    /**
     * 查询供应商预约送料
     *
     * @param id 供应商预约送料主键
     * @return 供应商预约送料
     */
    @Override
    public SupplierReservation selectSupplierReservationById(Long id)
    {
        return supplierReservationMapper.selectSupplierReservationById(id);
    }

    /**
     * 查询供应商预约送料列表
     *
     * @param supplierReservation 供应商预约送料
     * @return 供应商预约送料
     */
    @Override
    public List<SupplierReservation> selectSupplierReservationList(SupplierReservation supplierReservation)
    {
        return supplierReservationMapper.selectSupplierReservationList(supplierReservation);
    }

    @Override
    public List<SupplierReservationVo> selectSupplierList(SupplierReservation supplierReservation) {
        List<SupplierReservation> list = supplierReservationMapper.selectSupplierReservationList(supplierReservation);
        if(CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        List<Long> carIds = list.stream().map(SupplierReservation::getCarId).collect(Collectors.toList());
        List<Long> factoryIds = list.stream().map(SupplierReservation::getFactoryId).collect(Collectors.toList());
        List<Long> fuelIds = list.stream().map(SupplierReservation::getFuelId).collect(Collectors.toList());
        List<SupplierCar> supplierCars = supplierCarMapper.selectSupplierCarByIds(carIds);
        List<FactoryInfo> factoryInfos = factoryInfoMapper.selectFactoryInfoByIds(factoryIds);
        List<FactoryFuel> factoryFuels = factoryFuelMapper.selectFactoryFuelByIds(fuelIds);
        Map<Long, String> carMap = supplierCars.stream().collect(Collectors.toMap(SupplierCar::getId, s -> s.getCarNum()));
        Map<Long, String> factoryMap = factoryInfos.stream().collect(Collectors.toMap(FactoryInfo::getId, f -> f.getName()));
        Map<Long, String> fuelMap = factoryFuels.stream().collect(Collectors.toMap(FactoryFuel::getId, f -> f.getName()));
        List<SupplierReservationVo> supplierReservationVos = BeanUtil.copyProperties(list, SupplierReservationVo.class);
        supplierReservationVos.forEach(s->{
            s.setFactoryName(factoryMap.get(s.getFactoryId()));
            s.setFuelName(fuelMap.get(s.getFuelId()));
            s.setCarNum(carMap.get(s.getCarId()));
        });
        return supplierReservationVos;
    }

    /**
     * 新增供应商预约送料
     *
     * @param supplierReservation 供应商预约送料
     * @return 结果
     */
    @Override
    public int insertSupplierReservation(SupplierReservation supplierReservation)
    {
        //supplierReservation.setReservationTime(DateUtils.getNowDate());
        Long factoryId = supplierReservation.getFactoryId();
        Long fuelId = supplierReservation.getFuelId();
        Date reservationDate = supplierReservation.getReservationDate();
        String reservationDateStr = DateUtils.dateTime(reservationDate);
        FactoryReceivingPlan factoryReceivingPlan = factoryReceivingPlanMapper.selectFactoryReceivingPlan(factoryId,fuelId,reservationDateStr);
        if(factoryReceivingPlan == null){
            throw new ServiceException("工厂今日没有此燃料的收货计划");
        }
        SupplierCar supplierCar = supplierCarMapper.selectSupplierCarById(supplierReservation.getCarId());
        SupplierReservation reservation = supplierReservationMapper.selectSupplierReservationByCarNum(reservationDateStr, supplierCar.getCarNum());
        if(reservation != null){
            throw new ServiceException("车牌："+supplierCar.getCarNum()+"今日已预约");
        }
        Double quantity = factoryReceivingPlan.getQuantity();
        boolean compare = Arith.compare(supplierReservation.getQuantity(), quantity);
        if(compare){
            throw new ServiceException("预约数量不能高于计划收货数量");
        }
        Double sumQuantity = supplierReservationMapper.selectSupplierReservationCount(factoryId,reservationDateStr);
        double sub = Arith.sub(quantity, sumQuantity);
        boolean compare1 = Arith.compare( supplierReservation.getQuantity(),sub);
        if(compare1){
            throw new ServiceException("可预约的数量为："+sub+"，当前已超出可预约数量");
        }
        supplierReservation.setCreateTime(DateUtils.getNowDate());
        return supplierReservationMapper.insertSupplierReservation(supplierReservation);
    }

    /**
     * 修改供应商预约送料
     *
     * @param supplierReservation 供应商预约送料
     * @return 结果
     */
    @Override
    public int updateSupplierReservation(SupplierReservation supplierReservation)
    {
        return supplierReservationMapper.updateSupplierReservation(supplierReservation);
    }

    /**
     * 批量删除供应商预约送料
     *
     * @param ids 需要删除的供应商预约送料主键
     * @return 结果
     */
    @Override
    public int deleteSupplierReservationByIds(Long[] ids)
    {
        return supplierReservationMapper.deleteSupplierReservationByIds(ids);
    }

    /**
     * 删除供应商预约送料信息
     *
     * @param id 供应商预约送料主键
     * @return 结果
     */
    @Override
    public int deleteSupplierReservationById(Long id)
    {
        return supplierReservationMapper.deleteSupplierReservationById(id);
    }

    @Override
    public SupplierReservationDataVo selectSupplierReservationByCarNum(String currentDate, String carNum) {
        SupplierReservation supplierReservation = supplierReservationMapper.selectSupplierReservationByCarNum(currentDate, carNum);
        if(supplierReservation == null){
            return null;
        }
        SupplierCar supplierCar = supplierCarMapper.selectSupplierCarById(supplierReservation.getCarId());
        FactoryFuel factoryFuel = factoryFuelMapper.selectFactoryFuelById(supplierReservation.getFuelId());
        SupplierInfo supplierInfo = supplierInfoMapper.selectSupplierInfoById(supplierReservation.getSupplierId());
        SupplierReservationDataVo supplierReservationDataVo = BeanUtil.copyProperties(supplierReservation, SupplierReservationDataVo.class);
        supplierReservationDataVo.setCarNum(supplierCar.getCarNum());
        supplierReservationDataVo.setFuelName(factoryFuel.getName());
        supplierReservationDataVo.setSupplierName(supplierInfo.getName());
        return supplierReservationDataVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signUp(Long id) {
        SupplierReservation supplierReservation = supplierReservationMapper.selectSupplierReservationById(id);
        if(supplierReservation == null){
            throw new ServiceException("预约不存在");
        }
        String reservationDate = DateUtils.dateTime(supplierReservation.getReservationDate());
        FuelPound exist = fuelPoundMapper.selectFuelPoundByCarId(supplierReservation.getCarId(),reservationDate);
        if(exist != null){
            throw new ServiceException("已经签到了，请勿重复签到");
        }
        SupplierCar supplierCar = supplierCarMapper.selectSupplierCarById(supplierReservation.getCarId());
        FactoryFuel factoryFuel = factoryFuelMapper.selectFactoryFuelById(supplierReservation.getFuelId());
        SupplierInfo supplierInfo = supplierInfoMapper.selectSupplierInfoById(supplierReservation.getSupplierId());
        FactoryInfo factoryInfo = factoryInfoMapper.selectFactoryInfoById(supplierReservation.getFactoryId());

        SupplierReservation update =new SupplierReservation();
        update.setId(id);
        update.setState(1);
        supplierReservationMapper.updateSupplierReservation(update);

        FactoryFuelRule ruleQuery = new FactoryFuelRule();
        ruleQuery.setFuelId(supplierReservation.getFuelId());
        List<FactoryFuelRule> factoryFuelRules = factoryFuelRuleMapper.selectFactoryFuelRuleList(ruleQuery);
        List<FactoryFuelRuleSaveVo> factoryFuelRuleSaveVos = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(factoryFuelRules)){
            factoryFuelRuleSaveVos = BeanUtil.copyProperties(factoryFuelRules, FactoryFuelRuleSaveVo.class);
        }

        FuelPound fuelPound = new FuelPound();
        fuelPound.setFuelContractPrice(factoryFuel.getPrice());
        fuelPound.setSupplierId(supplierReservation.getSupplierId());
        fuelPound.setFactoryId(supplierReservation.getFactoryId());
        fuelPound.setCarId(supplierReservation.getCarId());
        fuelPound.setFuelId(supplierReservation.getFuelId());
        fuelPound.setReservationTime(supplierReservation.getReservationTime());
        fuelPound.setReservationDate(supplierReservation.getReservationDate());
        fuelPound.setFactoryName(factoryInfo.getName());
        fuelPound.setSupplierName(supplierInfo.getName());
        fuelPound.setFuelName(factoryFuel.getName());
        fuelPound.setCarNum(supplierCar.getCarNum());
        fuelPound.setCreateTime(new Date());
        fuelPound.setSignTime(new Date());
        fuelPound.setCalcRules(JsonUtils.obj2Json(factoryFuelRuleSaveVos));
        fuelPoundMapper.insertFuelPound(fuelPound);
    }

    @Override
    public List<SupplierReservationDataVo> selectSupplierReservationPageList(SupplierReservationQuery supplierReservation) {
        return supplierReservationMapper.selectSupplierReservationPageList(supplierReservation);
    }
}
